package com.pe.pgn.clubpgn.dao.impl;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import com.pe.pgn.clubpgn.common.CLPConstantes;
import com.pe.pgn.clubpgn.dao.TopeDao;
import com.pe.pgn.clubpgn.dao.hibernate.GenericDaoHibernate;
import com.pe.pgn.clubpgn.domain.ClpdTope;
import com.pe.pgn.clubpgn.webapp.util.ValidationUtil;

@Repository("topeDao")
public class TopeDaoImpl  extends GenericDaoHibernate<ClpdTope, Long> implements TopeDao {

	public TopeDaoImpl() {
		super(ClpdTope.class);
	}
	private JdbcTemplate jdbcTemplate;
	
	@Autowired
	public void setDataSource(DataSource dataSource) {
		this.jdbcTemplate = new JdbcTemplate(dataSource);
	}

	public void eliminarTope(Long id) {
		StringBuffer query = new StringBuffer();
		query.append(" update clpd_tope ");
		query.append(" set ");
		query.append(" 		st_tope  = '").append(CLPConstantes.ST_FALSO).append("' ,");
		query.append(" 		co_usuario_modificador = '").append(getUsuarioLogueado().getUsername()).append("' ,");
		query.append(" 		da_fecha_modificacion = sysdate ");
		query.append(" where 1 = 1  ");
		query.append(" and id= ").append(id);
		query.append(" and st_tope='"+CLPConstantes.ST_VERDADERO+"' ");
		
		jdbcTemplate.update(query.toString());
		getHibernateTemplate().flush();
		
	}

	@SuppressWarnings("rawtypes")
	@Override
	public int guardarTope(Long id,String deTope,String stTipoTope,
		Long coClienteEmpresa,BigDecimal vaPorcentaje) {
		
		StringBuffer sql = new StringBuffer();
		Long sequencia = null;
		int resultado = 0;		
		int conteoRojo = 0;
		
		if(stTipoTope.equals(CLPConstantes.ST_TOPE_ROJO)){
			
			sql = new StringBuffer();
			sql.append(" select count(*) ");
			sql.append(" from clpd_tope ");
			sql.append(" where st_tipo_tope = '").append(CLPConstantes.ST_TOPE_ROJO).append("'");
			
			if(id > 0)
			sql.append(" and id != ").append(id);
			sql.append(" and co_cliente_empresa = ").append(coClienteEmpresa);
			sql.append(" and st_tope = '").append(CLPConstantes.ST_VERDADERO).append("'");
			conteoRojo = jdbcTemplate.queryForInt(sql.toString());
			
			if(conteoRojo > 0){ //frk: quiere decir que ya existe un tope rojo
				resultado = -1;
			}else{
				//frk: obtengo la maxima cantidad de los topes que no son rojos
				//para que sea la referencia de tope minimo
				
				sql = new StringBuffer();
				sql.append(" select max(va_porcentaje) as porcentaje ");
				sql.append(" from clpd_tope ");
				sql.append(" where st_tipo_tope != '").append(CLPConstantes.ST_TOPE_ROJO).append("'");
				sql.append(" and co_cliente_empresa = ").append(coClienteEmpresa);
				sql.append(" and st_tope = '").append(CLPConstantes.ST_VERDADERO).append("'");
				
				if(id != null && !id.equals(new Long(-1))){
					sql.append("	and id !=  ").append(id);				
				}
				
				Map map = jdbcTemplate.queryForMap(sql.toString());
				if(map.get("porcentaje") != null){
					
					BigDecimal maxporcentaje = new BigDecimal
					(map.get("porcentaje").toString());
					
					if(vaPorcentaje.compareTo(maxporcentaje) <= 0){
						conteoRojo = -1; //para que no inserte
						resultado = -3; //para indicar que no puede ser menor o igual a un tipo inferior
					}
				}					
			}
			
		}else if(stTipoTope.equals(CLPConstantes.ST_TOPE_VERDE)){
			//frk: obtengo la minima cantidad de los topes que no sean verdes
			//para que sea el tope al que el tope verde no puede sobrepasar
			
			sql = new StringBuffer();
			sql.append(" select min(va_porcentaje) as porcentaje ");
			sql.append(" from clpd_tope ");
			sql.append(" where st_tipo_tope != '").append(CLPConstantes.ST_TOPE_VERDE).append("'");
			sql.append(" and co_cliente_empresa = ").append(coClienteEmpresa);
			sql.append(" and st_tope = '").append(CLPConstantes.ST_VERDADERO).append("'");
			Map map = jdbcTemplate.queryForMap(sql.toString());
			if(map.get("porcentaje") != null){
			
				BigDecimal maxporcentaje = new BigDecimal
				(map.get("porcentaje").toString());
				
				if(vaPorcentaje.compareTo(maxporcentaje) >= 0){
					conteoRojo = -1; //para que no inserte
					resultado = -2; //para indicar que no puede exceder o ser igual a un tipo superior
				}
			}				
		}else if(stTipoTope.equals(CLPConstantes.ST_TOPE_AMBAR)){
			//frk: obtengo la minima cantidad del tope rojo que es un tipo
			//superior al tipo ambar para que sea el tope al que no puede sobrepasar
			
			sql = new StringBuffer();
			sql.append(" select min(va_porcentaje) as porcentaje ");
			sql.append(" from clpd_tope ");
			sql.append(" where st_tipo_tope = '").append(CLPConstantes.ST_TOPE_ROJO).append("'");
			sql.append(" and co_cliente_empresa = ").append(coClienteEmpresa);
			sql.append(" and st_tope = '").append(CLPConstantes.ST_VERDADERO).append("'");
			
			if(id != null && !id.equals(new Long(-1))){
				sql.append("	and id !=  ").append(id);				
			}
			
			Map map = jdbcTemplate.queryForMap(sql.toString());
			if(map.get("porcentaje") != null){
				
				BigDecimal maxporcentaje = new BigDecimal
				(map.get("porcentaje").toString());
				
				if(vaPorcentaje.compareTo(maxporcentaje) >= 0){
					conteoRojo = -1; //para que no inserte
					resultado = -2; //para indicar que no puede exceder o ser igual a un tipo superior
				}
			}
			
			//frk: obtengo la maxima cantidad del tope verde que es un tipo
			//inferior al tipo ambar para que sea la referencia de tope minimo
			
			sql = new StringBuffer();
			sql.append(" select max(va_porcentaje) as porcentaje ");
			sql.append(" from clpd_tope ");
			sql.append(" where st_tipo_tope = '").append(CLPConstantes.ST_TOPE_VERDE).append("'");
			sql.append(" and co_cliente_empresa = ").append(coClienteEmpresa);
			sql.append(" and st_tope = '").append(CLPConstantes.ST_VERDADERO).append("'");
			
			if(id != null && !id.equals(new Long(-1))){
				sql.append("	and id !=  ").append(id);				
			}
			
			map = jdbcTemplate.queryForMap(sql.toString());
			if(map.get("porcentaje") != null){
				
				BigDecimal maxporcentaje = new BigDecimal
				(map.get("porcentaje").toString());
				
				if(vaPorcentaje.compareTo(maxporcentaje) <= 0){
					conteoRojo = -1; //para que no inserte
					resultado = -3; //para indicar que no puede ser menor o igual a un tipo inferior
				}
			}
		}
			
		if (id<0){
			if(conteoRojo == 0){
			
				sql = new StringBuffer();
				sql.append("select seq_tope.nextval from dual");
				sequencia = jdbcTemplate.queryForLong(sql.toString());
				String stEnviado = setearEnviadoSegunTopes(coClienteEmpresa,vaPorcentaje,null);
				
				sql = new StringBuffer();
				sql.append(" insert into clpd_tope (");
				sql.append("   id, de_tope,st_tipo_tope,co_cliente_empresa,");
				sql.append("   va_porcentaje,st_tope,co_usuario_creador,");
				sql.append("   da_fecha_creacion,st_enviado)  ");
				sql.append(" values("+sequencia+ ",'" + deTope.trim() +"',");
				sql.append("	'"+stTipoTope.trim()+"',"+coClienteEmpresa+",");
				sql.append("	 "+vaPorcentaje+",'"  +CLPConstantes.ST_VERDADERO + "',");
				sql.append("	'"+getUsuarioLogueado().getUsername()+ "',sysdate,'"+stEnviado+"')");
				resultado = jdbcTemplate.update(sql.toString());
			}		
			
		} else {
			if(conteoRojo == 0){
			
				String stEnviado = setearEnviadoSegunTopes(coClienteEmpresa,vaPorcentaje,id);
				sql = new StringBuffer();
				
				sql.append(" update clpd_tope set ");
				sql.append(" de_tope ='" + deTope).append("', ");
				sql.append(" va_porcentaje =" + vaPorcentaje).append(", ");
				sql.append(" st_tipo_tope ='" + stTipoTope).append("', ");
				sql.append(" st_enviado ='" + stEnviado).append("', ");
				sql.append(" co_usuario_modificador ='" +  getUsuarioLogueado().getUsername()).append(" ' ,");
				sql.append(" da_fecha_modificacion = sysdate ");
				sql.append(" where id = ").append(id);
				resultado = jdbcTemplate.update(sql.toString());
			}
		}		
		
		return resultado;
	}
	
	@SuppressWarnings("rawtypes")
	private String setearEnviadoSegunTopes(Long coClienteEmpresa, 
		BigDecimal vaPorcentaje, Long idTope) {

		String isEnviado = CLPConstantes.ST_FALSO;		
		StringBuffer query = new StringBuffer();
		
		query.append(" select tp.st_enviado, tp.st_tipo_tope ");
		query.append(" from clpd_tope tp ");
		query.append(" where tp.va_porcentaje >= ").append(vaPorcentaje);
		query.append(" and tp.st_tope = '"+CLPConstantes.ST_VERDADERO+"'");
		query.append(" and tp.co_cliente_empresa = ").append(coClienteEmpresa);
		
		if(idTope != null)
		query.append(" and tp.id != ").append(idTope);		
		query.append(" order by tp.va_porcentaje desc ");
		
		List list = jdbcTemplate.queryForList(query.toString());
		if(ValidationUtil.validateList(list)){
			for (int i = 0; i < list.size(); i++) {
				
				Map map = (Map)list.get(i);
				String stEnviado = String.valueOf(map.get("st_enviado"));
				if(stEnviado.equals(CLPConstantes.ST_VERDADERO)){
					isEnviado = CLPConstantes.ST_VERDADERO;
					break;
				}
			}			
		}
		
		return isEnviado;
	}

	@Override
	public ClpdTope obtenerTope(Long id) {
		ClpdTope tope = get(id);
		return tope;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<ClpdTope> obtenerTopes(Long id) {
		StringBuffer query = new StringBuffer();
		query.append(" select   ");		  
		query.append("  tope.id as id,");
		query.append("  tope.de_tope as deTope,");
		query.append("  tope.st_tipo_tope as stTipoTope,");
		query.append("  tope.co_cliente_empresa as coClienteEmpresa,");
		query.append("  tope.va_porcentaje as vaPorcentaje,");
		query.append("  tope.st_tope as habilitado");
		query.append("	from clpd_tope tope ");
		query.append("		where 1 = 1 ");
		query.append("  		and tope.st_tope = '"+CLPConstantes.ST_VERDADERO+"'  ");
		query.append(" 			and tope.co_cliente_empresa = ").append(id);
		query.append(" ORDER BY tope.id  ");
		System.out.println(query.toString());
		List<ClpdTope> listClpdTope = findListOfBeans(query.toString(), null,ClpdTope.class);
		if(!listClpdTope.isEmpty()){
			System.out.println(listClpdTope.size());
			return listClpdTope;
		}				
		return null;
	}

}
